package com.ste.domain;

import java.io.IOException;
import java.net.Socket;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.logging.Logger;

import com.ste.server.ReadClient;
import com.ste.server.Server;
import com.ste.server.WriteClient;
import com.ste.server.command.Command;

public class Client {
	private final Integer QUEUE_CAPACITY = 100;
	private Server server;
	private Socket socket;
	private String name;
	private Thread readClient;
	private Thread writeClient;
	private Integer orderId;
	private static Logger log = Logger.getLogger(Client.class.getName());
	private BlockingQueue<String> sendQueue = new ArrayBlockingQueue<String>(QUEUE_CAPACITY, true);

	public Client(Server server, String name, Socket socket) throws IOException {
		this.server = server;
		this.name = name;
		this.socket = socket;
		this.readClient = new Thread(new ReadClient(socket.getInputStream(), this));
		this.writeClient = new Thread(new WriteClient(socket.getOutputStream(), this));
	}

	public void start() {
		readClient.start();
		writeClient.start();
		log.info("Server threads started");
	}

	public boolean isAuthorizated() {
		return name != null;
	}

	public BlockingQueue<String> getSendQueue() {
		return sendQueue;
	}

	public void setSendQueue(BlockingQueue<String> sendQueue) {
		this.sendQueue = sendQueue;
	}

	public void sendMessage(String message) {
		sendQueue.add(message);
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public BlockingQueue<Command> getMessageQueue() {
		return server.getMessageQueue();
	}

	public Integer getOrderId() {
		return orderId++;
	}

	public void remove() {
		log.info("Client removing");
		if (!socket.isClosed()) {
			if (!socket.isInputShutdown()) {
				try {
					socket.getInputStream().close();
				} catch (IOException e) {
				}
			}
			if (!socket.isOutputShutdown()) {
				try {
					socket.getOutputStream().close();
				} catch (IOException e) {
				}
			}
			try {
				socket.close();
			} catch (IOException e) {
			}
		}
		server.remove(this);
	}
}
